package com.example.librarymanagementproject2.Common.aop;

import com.example.librarymanagementproject2.Common.config.RabbitConfig;
import com.example.librarymanagementproject2.Common.exception.GlobalException;
import com.example.librarymanagementproject2.Common.message.BorrowSuccessMessage;
import com.example.librarymanagementproject2.mapper.BookMapper;
import com.example.librarymanagementproject2.mapper.UserMapper;
import com.example.librarymanagementproject2.model.entity.Book;
import com.example.librarymanagementproject2.model.entity.BorrowRecord;
import com.example.librarymanagementproject2.model.entity.User;
import com.example.librarymanagementproject2.service.enums.EmailEnum;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.UUID;

/**
 * @ClassName BorrowRecordAspect
 * @Description TODO
 * @Author Kx
 * @Date 2025/10/28 15:25
 * @Version 1.0
 */
@Aspect
@Component
@RequiredArgsConstructor
public class BorrowRecordAspect {
    private final BookMapper bookMapper;
    private final UserMapper userMapper;
    private final RabbitTemplate rabbitTemplate;
    private final RedisTemplate<String, Object> redisTemplate;


    /**
     * @author: kx
     * @date: 2025/10/28 19:34
     * @param joinPoint : 切入点
     * @description: 借阅后置通知消息队列发送邮件
    */
    @AfterReturning(value = "execution(* com.example.librarymanagementproject2.service.impl.BorrowRecordServiceImpl.checkoutBook(..))")
    public void afterBorrowSuccessSendEmail(JoinPoint joinPoint) {
        try {
            // 获取所有参数
            Object[] args = joinPoint.getArgs();

            // 获取借阅记录信息
            BorrowRecord borrowRecord = (BorrowRecord) args[0];

            // 获取用户信息
            User user = userMapper.getUserById(borrowRecord.getUserId());
            // 获取图书信息
            Book book = bookMapper.getBookById(borrowRecord.getBookId());

            // 构建用户和图书数据传输信息
            BorrowSuccessMessage borrowSuccessMessage = new BorrowSuccessMessage();
            borrowSuccessMessage.setUser(user);
            borrowSuccessMessage.setBook(book);
            borrowSuccessMessage.setBorrowRecord(borrowRecord);

            // 发送队列消息
            // 创建消息唯一ID
            CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
            // 投递消息
            rabbitTemplate.convertAndSend(RabbitConfig.BORROW_RECORD_EXCHANGE, RabbitConfig.BORROW_RECORD_SUCCESS_ROUTING_KEY, borrowSuccessMessage, correlationData);
        } catch (AmqpException e) {
            throw new GlobalException(500, "消息发送失败");
        }
    }

    /**
     * @author: kx
     * @date: 2025/10/29 16:00
     * @param joinPoint : 切入点
     * @description: 验证码验证成功后置通知修改索引
    */
    @AfterReturning(value = "execution(* com.example.librarymanagementproject2.service.impl.BorrowRecordServiceImpl.verifyCodeAndUpdateStatus(..)) ||" +
            "execution(* com.example.librarymanagementproject2.service.impl.BorrowRecordServiceImpl.processBookReturn(..))")
    public void updateBorrowRecordIndexAfterCodeVerification(JoinPoint joinPoint) {
        // 获取所有参数
        Object[] args = joinPoint.getArgs();
        // 获取方法名
        String methodName = joinPoint.getSignature().getName();
        Long borrowRecordId;

        switch (methodName) {
            // 验证码校验并修改借阅状态
            case "verifyCodeAndUpdateStatus":
                // 获取用户id
                Long userId = (Long) args[1];
                // 获取用户信息
                User user = userMapper.getUserById(userId);
                if (user == null) {
                    throw new GlobalException(500, "用户不存在");
                }
                // 从缓存中获取验证码和借阅记录Id
                Map<String, Object> object = (Map<String, Object>) redisTemplate.opsForValue().get(EmailEnum.CAPTCHA_PREFIX.value() + user.getEmail());
                if (object == null) {
                    throw new GlobalException(500, "验证码已过期");
                }
                // 获取借阅记录Id
                borrowRecordId = (Long) object.get("borrowId");
                break;
            // 处理图书归还修改状态
            case "processBookReturn":
                borrowRecordId = (Long) args[0];
                break;
            default:
                return;
        }


        // 创建消息唯一ID
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        // 投递消息
        rabbitTemplate.convertAndSend(RabbitConfig.BORROW_RECORD_EXCHANGE, RabbitConfig.BORROW_RECORD_OPERATION_ROUTING_KEY, borrowRecordId, correlationData);
    }
}
